﻿#pragma once
/**@author 由W意波(LuoJun)编写*/

namespace LK
{
	/**
	@brief 表示一个以位为偏移单位的指针*/
	struct BitPtr
	{
		/**
		@brief 用以获取ptrValue*/
		static const size_t PtrValueMask = ((size_t)-1) ^ (sizeof(size_t) - 1);
		/**
		@brief 用以截取字节指针偏移*/
		static const size_t PtrMoveMask = sizeof(size_t) - 1;
		/**
		@brief 内部位偏移量最大值*/
		static const size_t BitMoveMax = ((sizeof(size_t) - 1) << 3) | 7;
		/**
		@brief 从指针进行构造*/
		BitPtr(const void* p) :ptrValue((size_t)p&PtrValueMask), bitMove(((size_t)p&PtrMoveMask) << 3) {}
		/**
		@brief 从指针和位偏移量进行构造*/
		BitPtr(const void* p, index_t bitShift)
		{
			if (bitShift < 0) { (unsigned char*&)p += (bitShift + 1) / 8 - 1; }
			else if (bitShift >= 8) { (unsigned char*&)p += bitShift >> 3; }
			ptrValue = (size_t)p&PtrValueMask;
			bitMove = (((size_t)p&PtrMoveMask) << 3) | (bitShift & 7);
		}
		/**
		@brief 直接传入成员数值进行构造*/
		BitPtr(size_t ptrVal, size_t bitMov) :ptrValue(ptrVal), bitMove(bitMov) {}
		/**
		@brief 获取size_t*指针*/
		size_t* GetPtr() { return (size_t*)ptrValue; }
		size_t const* GetPtr()const { return (size_t const*)ptrValue; }
		/**
		@brief 获取该指针所指定比特内容
		@return 如果指定位有内容则返回true
		@note 该操作不做指针为NULL检查*/
		bool Get()const { return (((*(size_t*)ptrValue) >> bitMove) & 1) != 0; }
		/**
		@brief 在该位指针所指向的位置起往高位获取64bit内容
		@return 返回获取的内容*/
		unsigned long long Get64()const { if (bitMove == 0)return *(unsigned long long*)ptrValue; return (*(unsigned long long*)ptrValue >> bitMove) | (*((unsigned long long*)ptrValue + 1) << (64 - bitMove)); }
		/**
		@brief 将该位指针指定位置起往高64bit的内容设置为ull
		@param [传入]参数ull表示设定内容
		@note 该操作不做指针为NULL检查*/
		void Set64(unsigned long long ull)
		{
			if (bitMove == 0)*(unsigned long long*)ptrValue = ull;
			else
			{
				*(unsigned long long*)ptrValue = (*(unsigned long long*)ptrValue&(((unsigned long long) - 1) >> (64 - bitMove))) | (ull << bitMove);
				*((unsigned long long*)ptrValue + 1) = (*((unsigned long long*)ptrValue + 1)&(((unsigned long long) - 1) << bitMove)) | (ull >> (64 - bitMove));
			}
		}
		/**
		@brief 将该位指针指定位设置为boolean所指定的值
		@param [传入]参数boolean表示指定位设定内容
		@note 该操作不做指针为NULL检查*/
		void Set(bool boolean) { if (boolean)(*(size_t*)ptrValue) |= ((size_t)1 << bitMove); else (*(size_t*)ptrValue) = (*(size_t*)ptrValue)&((*(size_t*)ptrValue) ^ ((size_t)1 << bitMove)); }
		/**
		@brief 将该位指针指定位状态翻转
		@note 该操作不做指针为NULL检查*/
		void Flip() { (*(size_t*)ptrValue) ^= ((size_t)1 << bitMove); }
		/**
		@brief 获取位偏移量*/
		size_t GetBitMove()const { return bitMove; }
		/**
		@自增*/
		BitPtr& operator++() { if (bitMove == BitMoveMax) { bitMove = 0; ptrValue += sizeof(size_t); } else ++bitMove; return*this; }
		BitPtr operator++(int) { BitPtr tmp(*this); ++*this; return tmp; }
		/**
		@brief 相加*/
		BitPtr operator+(size_t num)const { return BitPtr((void*)ptrValue, bitMove + num); }
		/**
		@brief 相加*/
		BitPtr& operator+=(size_t num)
		{
			bitMove += num;
			if ((index_t)bitMove < 0) { ptrValue += ((index_t)bitMove + 1) / 8 - 1; }
			else if (bitMove >= 8) { ptrValue += bitMove >> 3; }
			bitMove = ((ptrValue&PtrMoveMask) << 3) | (bitMove & 7);
			ptrValue &= PtrValueMask;
			return *this;
		}
		/**
		@自减*/
		BitPtr& operator--() { if (bitMove == 0) { bitMove = BitMoveMax; ptrValue -= sizeof(size_t); } else --bitMove; return*this; }
		BitPtr operator--(int) { BitPtr tmp(*this); --*this; return tmp; }
		/**
		@brief 相减*/
		size_t operator-(BitPtr const& bp)const { return ((ptrValue << 3) | bitMove) - ((bp.ptrValue << 3) | bp.bitMove); }
		/**
		@brief 相减*/
		BitPtr operator-(size_t num)const { return BitPtr((void*)ptrValue, bitMove - num); }
		/**
		@brief 相减*/
		BitPtr& operator-=(size_t num)
		{
			bitMove -= num;
			if ((index_t)bitMove < 0) { ptrValue += ((index_t)bitMove + 1) / 8 - 1; }
			else if (bitMove >= 8) { ptrValue += bitMove >> 3; }
			bitMove = ((ptrValue&PtrMoveMask) << 3) | (bitMove & 7);
			ptrValue &= PtrValueMask;
			return *this;
		}
		/**
		@brief 比较*/
		bool operator==(BitPtr const& bp)const { return ptrValue == bp.ptrValue&&bitMove == bp.bitMove; }
		bool operator!=(BitPtr const& bp)const { return ptrValue != bp.ptrValue || bitMove != bp.bitMove; }
		bool operator>=(BitPtr const& bp)const { if (ptrValue != bp.ptrValue)return ptrValue > bp.ptrValue; return bitMove >= bp.bitMove; }
		bool operator<=(BitPtr const& bp)const { if (ptrValue != bp.ptrValue)return ptrValue < bp.ptrValue; return bitMove <= bp.bitMove; }
		bool operator>(BitPtr const& bp)const { if (ptrValue != bp.ptrValue)return ptrValue > bp.ptrValue; return bitMove > bp.bitMove; }
		bool operator<(BitPtr const& bp)const { if (ptrValue != bp.ptrValue)return ptrValue < bp.ptrValue; return bitMove < bp.bitMove; }
		index_t CompareWith(BitPtr const& bp)const { if (ptrValue != bp.ptrValue)return ptrValue > bp.ptrValue ? 1 : -1; return bitMove > bp.bitMove ? 1 : bitMove < bp.bitMove ? -1 : 0; }
		/**
		@brief 输出指向数据的字符串表示
		@param [传入]参数t表示读取并输出的位的数量，如果t<0，将逆向逆序输出字符串，如果t等于0，将输出该指针数据内容*/
		PString ToString(index_t t = 1);
		/**
		@brief operator[]只读重载，如果指定位为1则返回true，否则返回false*/
		bool operator[](index_t id)const
		{
			id += bitMove;
			if (id < 0)return (*((size_t*)ptrValue + (id - (index_t)(sizeof(size_t) * 8 - 1)) / (sizeof(size_t) * 8)) >> (id&((sizeof(size_t) * 8) - 1)) & 1);
			return (*((size_t*)ptrValue + id / (sizeof(size_t) * 8)) >> (id&((sizeof(size_t) * 8) - 1)) & 1);
		}
	private:
		/**@brief 实际的地址*/
		size_t ptrValue;
		/**@brief 位偏移量*/
		size_t bitMove;
	};
	/**
	@brief 包含位操作相关的静态成员函数*/
	struct Bits
	{
		/**
		@brief 将无符号整数m1和m2乘积的结果的高64bit保存到p所指向的内存中，并返回低64位内容
		@param [传入]参数m1表示64位无符号整数（乘数1）
		@param [传入]参数m2表示64位无符号整数（乘数2）
		@param [写出]参数p表示用以输出高64bit相乘结果
		@return 返回低64bit结果*/
		static inline u64 Multiply(u64 m1, u64 m2, u64 *p)
		{
#ifdef __INTRIN_H_//优先采用内部函数
#ifdef _M_X64
			return _umul128(m1, m2, p);
#endif
#endif
			u64 tmp1 = (((u64)(u32)m1)*((u64)((u32)m2))) >> 32;
			u64 tmp2 = ((u32)m1)*(m2 >> 32);
			u64 tmp3 = ((u32)m2)*(m1 >> 32);
			u64 tmp4 = tmp1 + (u32)tmp2 + (u32)tmp3;
			*p = (m1 >> 32)*(m2 >> 32) + (tmp2 >> 32) + (tmp3 >> 32) + (tmp4 >> 32);
			return m1*m2;
		}
		/**
		@brief 将high64和low64表示的128位无符号整数除以一个64位无符号整数num，返回所得结果的低64位数据，余数保存到p所指向变量中
		@param [传入]参数high64表示被除数的高64bit
		@param [传入]参数low64表示被除数的低64bit
		@param [传入]参数num表示64位无符号除数
		@param [写出,可选]参数p用以输出余数
		@return 返回商
		@note 如果num为0将导致错误*/
		static u64 Divide(u64 high64, u64 low64, u64 num, u64*p = NULL);
		/**
		@brief 进行128位的左移操作并返回高位左移结果
		@param [传入]参数high64表示高64bit数据
		@param [传入]参数low64表示低64bit数据
		@param [传入]参数mov表示左移位数
		@return 返回位移所得高64位部分
		@note 参数mov必须小于64，否则结果将是不确定的*/
		static inline u64 ShiftLeft(u64 high64, u64 low64, u8 mov)
		{
			return (high64 << mov) | (low64 >> (64 - mov));
		}
		/**
		@brief 进行128位的右移操作并返回低位右移结果
		@param [传入]参数high64表示高64bit数据
		@param [传入]参数low64表示低64bit数据
		@param [传入]参数mov表示右移位数
		@return 返回位移所得低64位部分
		@note 参数mov必须小于64，否则结果将是不确定的*/
		static inline u64 ShiftRight(u64 high64, u64 low64, u8 mov)
		{
			return (high64 << (64 - mov)) | (low64 >> mov);
		}
		/**
		@brief 获取i前导0的比特数（重载以自动匹配位数）
		@param [传入]参数i为被测数字
		@return 返回被测数字高位0的位数
		@note 该函数为重载函数的一个版本，函数会根传入参数类型进行重载：
		@note 当传入参数为unsigned long或者unsigned int时将调用LeftZeroCount32函数，
		@note 当传入参数类型为unsigned long long时将调用LeftZeroCount64函数*/
		static inline index_t LeftZeroCount(u64 i)
		{
			return LeftZeroCount64(i);
		}
		static inline index_t LeftZeroCount(u32 i)
		{
			return LeftZeroCount32(i);
		}
		static inline index_t LeftZeroCount(unsigned int i) { return LeftZeroCount((u32)i); }
		/**
		@brief 获取i前导0的比特数（32位）
		@param [传入]参数n表示一个32位的被测数字
		@return 返回该数字高位为0的bit数量，比如LeftZeroCount32(0)得到32，LeftZeroCount32(9)得到28*/
		static index_t LeftZeroCount32(u32 n)
		{
			static index_t(*p)(u32);
			if (p)return p(n);
			//测试高速算法是否准确
			u32 test = 1;
			int i = 0;
			for (; i < 32; ++i, test <<= 1)if (_1LeftZeroCount32(test) != _LeftZeroCount32(test))break;
			if (i == 32) { p = _1LeftZeroCount32; }
			else {
				test = 1; i = 0;
				for (; i < 32; ++i, test <<= 1)if (_2LeftZeroCount32(test) != _LeftZeroCount32(test))break;
				if (i == 32) { p = _2LeftZeroCount32; }
				else p = _LeftZeroCount32;
			}
			return p(n);
		}
		/**
		@brief 获取i前导0的比特数（64位）
		@param [传入]参数n表示一个64位的被测数字
		@return 返回该数字高位为0的bit数量，比如LeftZeroCount64(0)得到64，LeftZeroCount64(0x11)得到59*/
		static index_t LeftZeroCount64(u64 n)
		{
			static index_t(*p)(u64);
			if (p)return p(n);
			//测试高速算法是否准确
			u64 test = 1;
			int i = 0;
			for (; i < 64; ++i, test <<= 1)if (_1LeftZeroCount64(test) != _LeftZeroCount64(test))break;
			if (i == 64) { p = _1LeftZeroCount64; }
			else {
				test = 1; i = 0;
				for (; i < 64; ++i, test <<= 1)if (_2LeftZeroCount64(test) != _LeftZeroCount64(test))break;
				if (i == 64) { p = _2LeftZeroCount64; }
				else p = _LeftZeroCount64;
			}
			return p(n);
		}
		/*获取i前导0的比特数（32位保守算法）*/
		static index_t _LeftZeroCount32(u32 i);
		/*获取i前导0的比特数（64位保守算法）*/
		static index_t _LeftZeroCount64(u64 i);
		//32位高速算法1
		static inline index_t _1LeftZeroCount32(u32 i)
		{
#ifdef __INTRIN_H_
#ifdef _M_IX86
			if (i == 0)return 32;
			return 31 ^ __lzcnt(i);
#else
#ifdef _M_X64
			if (i == 0)return 32;
			return 31 ^ __lzcnt(i);
#endif
#endif
#endif
			return 0;
		}
		//64位高速算法1
		static inline index_t _1LeftZeroCount64(u64 i)
		{
#ifdef __INTRIN_H_
#ifdef _M_IX86
			if (i < 0x100000000)
			{
				if (i == 0)return 64;
				return 63 ^ __lzcnt((u32)i);
			}
			return 31 ^ __lzcnt((unsigned int)(i >> 32));
#else
#ifdef _M_X64
			if (i == 0)return 64;
			return 63 ^ __lzcnt64(i);
#endif
#endif
#endif
			return 0;
		}
		//32位高速算法2
		static inline index_t _2LeftZeroCount32(u32 i)
		{
#ifdef __INTRIN_H_
#ifdef _M_IX86
			if (i == 0)return 32;
			return __lzcnt(i);
#else
#ifdef _M_X64
			if (i == 0)return 32;
			return __lzcnt(i);
#endif
#endif
#endif
			return 0;
		}
		//64位高速算法2
		static inline index_t _2LeftZeroCount64(u64 i)
		{
#ifdef __INTRIN_H_
#ifdef _M_IX86
			if (i < 0x100000000)
			{
				if (i == 0)return 64;
				return __lzcnt((u32)i);
			}
			return __lzcnt((unsigned int)(i >> 32));
#else
#ifdef _M_X64
			if (i == 0)return 64;
			return __lzcnt64(i);
#endif
#endif
#endif
			return 0;
		}
		/**
		@brief 获取i后导0的比特数（32位）
		@param [传入]参数i表示一个32位的被测数字
		@return 返回该数字低位为0的bit数量，比如RightZeroCount32(0)得到32，RightZeroCount32(0x30)得到4
		@note 该函数为重载函数的一个版本，函数会根传入参数类型进行重载：
		@note 当传入参数为unsigned long或者unsigned int时将调用RightZeroCount32函数，
		@note 当传入参数类型为unsigned long long时将调用RightZeroCount64函数*/
		static inline index_t RightZeroCount(unsigned int i) { return RightZeroCount32((u32)i); }
		static inline index_t RightZeroCount(u32 i) { return RightZeroCount32(i); }
		static inline index_t RightZeroCount(u64 i) { return RightZeroCount64(i); }
		/**
		@brief 获取i后导0的比特数（64位）
		@param [传入]参数i表示一个64位的被测数字
		@return 返回该数字低位为0的bit数量，比如RightZeroCount64(0)得到64，RightZeroCount64(0x10)得到4*/
		static index_t RightZeroCount64(u64 i);
		/**
		@brief 获取i后导0的比特数（32位）
		@param [传入]参数i表示一个32位的被测数字
		@return 返回该数字低位为0的bit数量，比如RightZeroCount32(0)得到32，RightZeroCount32(0x20)得到5*/
		static index_t RightZeroCount32(u32 i);
		/**
		@brief 以pData[0]的最低位的权重为0，进行64位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long long*型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最低位的权重为0，截取并返回权重为bitsmov~bitsmov+63的64位数据，超出数组范围的数据置0比如：
		@note 当bitsmov为0，len非0时，将返回pData[0]
		@note 当bitsmov为-1，len非0时，将返回pData[0]<<1
		@note 如果bitsmov为3，那么len为1时，将返回pData[0]>>3；len大于1时，将返回(pData[0]>>3)|(pData[1]<<61);*/
		static inline u64 GetWindow64Low64(cu64*pData, size_t len, s64 bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov <= -64)return 0;
			if (bitsmov <= 0)return *pData << (-bitsmov);
			register size_t index = (size_t)(bitsmov >> 6);
			if (index >= len)return 0;
			if ((bitsmov &= 63) == 0)return pData[index];
			return index == len - 1 ? (pData[index] >> bitsmov) : ShiftRight(pData[index + 1], pData[index], (unsigned char)bitsmov);
		}
		/**
		@brief 以pData[len-1]的最高位的权重为0，进行64位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long long*型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最高位的权重为0，截取并返回权重为bitsmov-63~bitsmov的64位数据，超出数组范围的数据置0比如：
		@note 当bitsmov为0，len非0时，将返回pData[len-1]
		@note 当bitsmov为1，len非0时，将返回pData[len-1]>>1
		@note 如果bitsmov为-3，那么len为1时，将返回pData[len-1]<<3；len大于1时，将返回(pData[len-1]<<3)|(pData[len-2]>>61);*/
		static inline u64 GetWindow64High64(cu64*pData, size_t len, s64 bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov >= 64)return 0;
			if (bitsmov >= 0)return *(pData + len - 1) >> (bitsmov);
			size_t index = (size_t)(len - 1 + bitsmov / 64);
			if (index >= len)return 0;
			if ((bitsmov = (-bitsmov) & 63) == 0)return pData[index];
			return index == 0 ? (pData[0] << bitsmov) : ShiftLeft(pData[index], pData[index - 1], (unsigned char)bitsmov);
		}
		/**
		@brief 以pData[0]的最低位的权重为0，进行64位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long*型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最低位的权重为0，截取并返回权重为bitsmov~bitsmov+63的64位数据，超出数组范围的数据置0比如：
		@note 如果bitsmov为0，那么len为1时，将返回pData[0]；len大于1时，将返回pData[0] | (unsigned long long)pData[1]<<32
		@note 如果bitsmov为-1，那么len为1时，将返回pData[0]<<1；len大于1时，将返回pData[0]<<1 | (unsigned long long)pData[1]<<33
		@note 如果bitsmov为3，那么len为1时，将返回pData[0]>>3；len为2时，将返回(pData[0]>>3) | (unsigned long long)pData[1]<<29；len大于2时，将返回(pData[0]>>3) | (unsigned long long)pData[1]<<29| (unsigned long long)pData[2]<<61*/
		static inline u64 GetWindow64Low32(cu32*pData, size_t len, long bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov <= -64)return 0;
			if (bitsmov <= 0)
			{
				if (len > 1)return *(u64*)pData << (-bitsmov);
				return (u64)*pData << (-bitsmov);
			}
			register size_t index = bitsmov >> 5;
			if (index >= len)return 0;
			if ((bitsmov &= 31) == 0)return index == len - 1 ? pData[index] : *(u64 *)(pData + index);
			return index == len - 1 ? (pData[index] >> bitsmov) :
				index == len - 2 ? (*(u64 *)(pData + index) >> bitsmov) :
				ShiftRight(pData[index + 2], *(u64 *)(pData + index), (unsigned char)bitsmov);
		}
		/**
		@brief 以pData[len-1]的最高位的权重为0，进行64位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long *型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最高位的权重为0，截取并返回权重为bitsmov-63~bitsmov的64位数据，超出数组范围的数据置0比如：
		@note 如果bitsmov为0，那么len为1时，将返回(unsigned long long)pData[len-1]<<32；len大于1时，将返回((unsigned long long)pData[len-1]<<32) | pData[len-2]
		@note 如果bitsmov为1，那么len为1时，将返回(unsigned long long)pData[len-1]<<31；len大于1时，将返回((unsigned long long)pData[len-1]<<31) | (pData[len-2]>>1)
		@note 如果bitsmov为-3，那么len为1时，将返回(unsigned long long)pData[len-1]<<35；len为2时，将返回((unsigned long long)pData[len-1]<<35) | ((unsigned long long)pData[len-2]<<3)；len大于2时，将返回((unsigned long long)pData[len-1]<<35) | ((unsigned long long)pData[len-2]<<3)| (pData[len-3]>>29)*/
		static inline u64 GetWindow64High32(cu32*pData, size_t len, long bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov >= 64)return 0;
			if (bitsmov >= 0) { if (len == 1)return ((u64)*(pData + len - 1) << 32) >> bitsmov; return *(u64*)(pData + len - 2) >> bitsmov; }
			register size_t index = len - 1 + bitsmov / 32;
			if (index >= len)return 0;
			if ((bitsmov = (-bitsmov) & 31) == 0) { if (index == 0)return (u64)pData[index] << 32; return *(u64*)(pData + index - 1); }
			return index == 0 ? ((u64)pData[0] << (32 + bitsmov)) :
				index == 1 ? (*(u64*)pData << bitsmov) :
				(*(u64*)(pData + index - 1) << bitsmov) | (*(u64*)(pData + index - 2) >> (32 - bitsmov));
		}
		/**
		@brief 以pData[0]的最低位的权重为0，进行32位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long long*型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最低位的权重为0，截取并返回权重为bitsmov~bitsmov+31的32位数据，超出数组范围的数据置0比如：
		@note 当bitsmov为0，len非0时，将返回*(unsigned long*)pData
		@note 当bitsmov为-1，len非0时，将返回*(unsigned long*)pData<<1
		@note 如果bitsmov为33，那么len为1时，将返回pData[0]>>33；len大于1时，将返回(pData[0]>>33)|(pData[1]<<29);*/
		static inline u32 GetWindow32Low64(cu64*pData, size_t len, s64 bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov <= -32)return 0;
			if (bitsmov <= 0)return (u32)(*pData << (-bitsmov));
			register size_t index = (size_t)(bitsmov >> 6);
			if (index >= len)return 0;
			if ((bitsmov &= 63) == 0)return (u32)pData[index];
			return (u32)(index == len - 1 ? (pData[index] >> bitsmov) :
				ShiftRight(pData[index + 1], pData[index], (unsigned char)bitsmov));
		}
		/**
		@brief 以pData[len-1]的最高位的权重为0，进行32位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long long*型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最高位的权重为0，截取并返回权重为bitsmov-31~bitsmov的32位数据，超出数组范围的数据置0比如：
		@note 当bitsmov为0，len非0时，将返回(unsigned long)(pData[len-1]>>32)
		@note 当bitsmov为1，len非0时，将返回(unsigned long)(pData[len-1]>>33)*/
		static inline u32 GetWindow32High64(cu64*pData, size_t len, s64 bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov >= 32)return 0;
			if (bitsmov >= 0)return (u32)(*(pData + len - 1) >> (bitsmov));
			size_t index = (size_t)(len - 1 + bitsmov / 64);
			if (index >= len)return 0;
			if ((bitsmov = (-bitsmov) & 63) == 0)return (u32)pData[index];
			return (index == 0 ? (pData[0] << bitsmov) : ((pData[index] << bitsmov) | ((pData[index - 1] >> (64 - bitsmov))))) >> 32;
		}
		/**
		@brief 以pData[0]的最低位的权重为0，进行32位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long*型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最低位的权重为0，截取并返回权重为bitsmov~bitsmov+31的32位数据，超出数组范围的数据置0比如：
		@note 当bitsmov为0，len非0时，将返回*pData
		@note 当bitsmov为-1，len非0时，将返回*pData<<1*/
		static inline u32 GetWindow32Low32(cu32*pData, size_t len, long bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov <= -32)return 0;
			if (bitsmov <= 0)return (u32)(*pData << (-bitsmov));
			register size_t index = (size_t)(bitsmov >> 5);
			if (index >= len)return 0;
			if ((bitsmov &= 31) == 0)return (u32)pData[index];
			return index == len - 1 ? (pData[index] >> bitsmov) : ((pData[index] >> bitsmov) | ((pData[index + 1] << (32 - bitsmov))));
		}
		/**
		@brief 以pData[len-1]的最高位的权重为0，进行32位数据窗口截取
		@param [传入]参数pData表示需要进行截取的数组(unsigned long*型)
		@param [传入]参数len表示pData数组的元素数
		@param [传入]参数bitsmov表示截取窗向左（高位）位移量，当bitsmov小于0时表示向右位移
		@return 返回截取到的内容
		@note 当len为0时将直接返回0。
		@note 该函数认为pData数组最高位的权重为0，截取并返回权重为bitsmov-31~bitsmov的32位数据，超出数组范围的数据置0比如：
		@note 当bitsmov为0，len非0时，将返回pData[len-1]
		@note 当bitsmov为1，len非0时，将返回pData[len-1]>>1*/
		static inline u32 GetWindow32High32(cu32*pData, size_t len, long bitsmov)
		{
			if (len == 0)return 0;
			if (bitsmov >= 32)return 0;
			if (bitsmov >= 0)return *(pData + len - 1) >> (bitsmov);
			size_t index = (size_t)(len - 1 + bitsmov / 32);
			if (index >= len)return 0;
			if ((bitsmov = (-bitsmov) & 31) == 0)return pData[index];
			return index == 0 ? (pData[0] << bitsmov) : ((pData[index] << bitsmov) | ((pData[index - 1] >> (32 - bitsmov))));
		}
		/**
		@brief 将指定unsigned long long数组中的一系列比特数据复制到另一处数组的指定内存中，两处内存区域不可重叠
		@param [传入,写出]参数pDest表示目标数组（unsigned long long[]）
		@param [传入]参数destStartBitPositon表示起始写入位偏移，可以小于0
		@param [传入]参数pSource表示源数据数组（unsigned long long[]）
		@param [传入]参数sourceStartBitPositon表示源数据起始复制位偏移，可以小于0
		@param [传入]参数bitsCount表示要复制的比特数
		@warning 源数据区域和目标数据区域不可重叠。
		@note 该函数能精确地进行位写入，而不影响写入比特位之外的内容*/
		static void Copy64(u64* pDest, s64 destStartBitPositon, cu64* pSource, s64 sourceStartBitPositon, u64 bitsCount);
		/**
		@brief 将指定unsigned long数组中的一系列比特数据复制到另一处数组的指定内存中，两处内存区域不可重叠
		@param [传入,写出]参数pDest表示目标数组（unsigned long[]）
		@param [传入]参数destStartBitPositon表示起始写入位偏移，可以小于0
		@param [传入]参数pSource表示源数据数组（unsigned long[]）
		@param [传入]参数sourceStartBitPositon表示源数据起始复制位偏移，可以小于0
		@param [传入]参数bitsCount表示要复制的比特数
		@warning 源数据区域和目标数据区域不可重叠。
		@note 该函数能精确地进行位写入，而不影响写入比特位之外的内容*/
		static void Copy32(u32* pDest, long destStartBitPositon, cu32* pSource, long sourceStartBitPositon, u32 bitsCount);
		/**
		@brief 从pSource指向内存的startBitPositon位起复制bitsCount比特到pDestination指向内存的destinationBitPosition位处。
		@param [传入,写出]参数pDest指向目标内存区以复制内容
		@param [传入]参数destStartBitPositon表示目标写出起始位偏移（可以小于0）
		@param [传入]参数pSource指向源数据以供读取复制
		@param [传入]参数sourceStartBitPositon表示起始位偏移（可以小于0）
		@param [传入]参数bitsCount表示需要复制的比特数量
		@warning 源内存跟目标内存不能重叠，否则将出现意外
		@note 该函数能精确地进行位写入，而不影响写入比特位之外的内容*/
		static void Copy(void* pDest, index_t destStartBitPositon, const void* pSource, index_t sourceStartBitPositon, size_t bitsCount)
		{
			destStartBitPositon += ((size_t)pDest&(sizeof(size_t) - 1)) * 8;
			size_t* pd = (size_t*)((size_t)pDest & (~(sizeof(size_t) - 1)));
			sourceStartBitPositon += ((size_t)pSource&(sizeof(size_t) - 1)) * 8;
			size_t* ps = (size_t*)((size_t)pSource & (~(sizeof(size_t) - 1)));
			if (destStartBitPositon < 0) { pd += (destStartBitPositon - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); destStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			else if (destStartBitPositon >= (index_t)(sizeof(size_t) * 8)) { pd += destStartBitPositon / ((index_t)sizeof(size_t) * 8); destStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			if (sourceStartBitPositon < 0) { ps += (sourceStartBitPositon - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); sourceStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			else if (sourceStartBitPositon >= (index_t)(sizeof(size_t) * 8)) { ps += sourceStartBitPositon / ((index_t)sizeof(size_t) * 8); sourceStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			if (sizeof(size_t) == 8)Copy64((u64*)pd, destStartBitPositon, (u64*)ps, sourceStartBitPositon, bitsCount);
			else Copy32((u32*)pd, (long)destStartBitPositon, (u32*)ps, (long)sourceStartBitPositon, (u32)bitsCount);
		}
		/**
		@brief 将指定unsigned long long数组中的一系列比特数据复制到另一处数组的指定内存中，两处内存区域可以重叠
		@param [传入,写出]参数pDest表示目标数组（unsigned long long[]）
		@param [传入]参数destStartBitPositon表示起始写入位偏移，可以小于0
		@param [传入]参数pSource表示源数据数组（unsigned long long[]）
		@param [传入]参数sourceStartBitPositon表示源数据起始复制位偏移，可以小于0
		@param [传入]参数bitsCount表示要复制的比特数
		@note 源数据区域和目标数据区域可以重叠。
		@note 该函数能精确地进行位写入，而不影响写入比特位之外的内容*/
		static void Move64(u64* pDest, s64 destStartBitPositon, cu64* pSource, s64 sourceStartBitPositon, u64 bitsCount);
		/**
		@brief 将指定unsigned long数组中的一系列比特数据复制到另一数组的指定内存中，两处内存区域可以重叠
		@param [传入,写出]参数pDest表示目标数组（unsigned long[]）
		@param [传入]参数destStartBitPositon表示起始写入位偏移，可以小于0
		@param [传入]参数pSource表示源数据数组（unsigned long[]）
		@param [传入]参数sourceStartBitPositon表示源数据起始复制位偏移，可以小于0
		@param [传入]参数bitsCount表示要复制的bit数量
		@note 源数据区域和目标数据区域可以重叠。
		@note 该函数能精确地进行位写入，而不影响写入比特位之外的内容*/
		static void Move32(u32* pDest, long destStartBitPositon, cu32* pSource, s32 sourceStartBitPositon, u32 bitsCount);
		/**
		@brief 将指定内存中的一系列比特数据复制到另一数组的指定内存中，两处内存区域可以重叠
		@param [传入,写出]参数pDest表示目标内存
		@param [传入]参数destStartBitPositon表示起始写入位偏移，可以小于0
		@param [传入]参数pSource表示源数据内存
		@param [传入]参数sourceStartBitPositon表示源数据起始复制位偏移，可以小于0
		@param [传入]参数bitsCount表示要复制的比特数
		@note 源数据区域和目标数据区域可以重叠。
		@note 该函数能精确地进行位写入，而不影响写入比特位之外的内容*/
		static void Move(void* pDest, index_t destStartBitPositon, void const* pSource, index_t sourceStartBitPositon, size_t bitsCount)
		{
			destStartBitPositon += ((size_t)pDest&(sizeof(size_t) - 1)) * 8;
			size_t* pd = (size_t*)((size_t)pDest & (~(sizeof(size_t) - 1)));
			sourceStartBitPositon += ((size_t)pSource&(sizeof(size_t) - 1)) * 8;
			size_t* ps = (size_t*)((size_t)pSource & (~(sizeof(size_t) - 1)));
			if (destStartBitPositon < 0) { pd += (destStartBitPositon - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); destStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			else if (destStartBitPositon >= (index_t)(sizeof(size_t) * 8)) { pd += destStartBitPositon / ((index_t)sizeof(size_t) * 8); destStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			if (sourceStartBitPositon < 0) { ps += (sourceStartBitPositon - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); sourceStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			else if (sourceStartBitPositon >= (index_t)(sizeof(size_t) * 8)) { ps += sourceStartBitPositon / ((index_t)sizeof(size_t) * 8); sourceStartBitPositon &= (sizeof(size_t) * 8) - 1; }
			if (sizeof(size_t) == 8)Move64((u64*)pd, destStartBitPositon, (u64*)ps, sourceStartBitPositon, bitsCount);
			else Move32((u32*)pd, (long)destStartBitPositon, (u32*)ps, (long)sourceStartBitPositon, (u32)bitsCount);
		}
		/**
		@brief 比较两块指定位区域的大小，从高位往低位比较
		@param [传入]参数p1表示用以进行比较的第一个数据指针
		@param [传入]参数startBitPositon1表示第一块区域的起始位偏移
		@param [传入]参数p2表示用以进行比较的第二个数据指针
		@param [传入]参数startBitPositon2表示第二块区域的起始位偏移
		@param [传入]参数bitsCount表示进行比较的位数量，当此参数为0时将直接返回0
		@return 返回值为1时，说明p1表示的内容大于p2代表的内容，返回值为-1时则小于，返回值为0时说明两个区域的内容完全一样
		@note p1和p2所表示的内存区域可以重叠*/
		static index_t Compare(void const* p1, index_t startBitPositon1, void const* p2, index_t startBitPositon2, size_t bitsCount);
		/**
		@brief 按高位对齐（允许相对位移）比较两处指定的内容并返回偏差结果
		@param [传入]参数p1表示内容1的指针
		@param [传入]参数startBitPosition1表示内容1的起始位偏移（可以小于0）
		@param [传入]参数bitsCount1表示内容1的位数
		@param [传入]参数p2表示内容2的指针
		@param [传入]参数startBitPosition2表示内容2的起始位偏移（可以小于0）
		@param [传入]参数bitsCount2表示内容2的位数
		@param [传入,可选]参数mov表示内容2的最高位相对内容1的最高位的偏移量。当mov>0时，表示内容2的最高位比内容1的最高位的权重要大；当mov<0时则反之
		@return 当两者完全相等时返回0。如果内容1大于内容2则返回数字大于0，如果内容1小于内容2则返回数字小于0，而且返回数字的绝对值表示比较最高位到偏差位的位数（>=1）
		@note 比较时，两者最高位按mov指定的位移对齐。指定区域外的内容按0看待。*/
		static index_t DifferenceIndexHigh(void const *p1, index_t startBitPosition1, size_t bitsCount1, void const*p2, index_t startBitPosition2, size_t bitsCount2, index_t mov = 0);
		/**
		@brief 对指定的区域进行移位操作
		@param [传入,写出]参数p表示内存指针
		@param [传入]参数startBitPosition表示起始位偏移
		@param [传入]参数bitsCount表示内容位数量
		@param [传入]参数mov指定位移方向和数量，比如mov为1时表示向左移动1bit，mov为-2时表示向右移动2bit
		@param [传入]参数mask表示移空位置填补方法，当mask为false时用0填补，当mask为true时用1填补*/
		static void Shift(void *p, index_t startBitPosition, size_t bitsCount, index_t mov, bool mask = false);
		/**
		@brief 将p所指内存从startBitPosition位置起的bitsCount比特全部设置为bitValue的值。
		@param [传入,写出]参数p指向目标内存区以写入内容
		@param [传入]参数startBitPositon表示起始比特偏移
		@param [传入]参数bitsCount表示需要设置的比特数量
		@param [传入,可选]参数bitValue表示目标改变值，默认为false*/
		static void Set(void* p, index_t startBitPosition, size_t bitsCount, bool b);
		/**
		@brief 将p指向的内存的startBitPosition比特位起bitsCount比特的数据进行mov比特位移
		@param [传入,写出]参数p指向目标内存
		@param [传入]参数startBitPosition表示起始比特偏移
		@param [传入]参数bitsCount表示操作的总比特位数
		@param [传入]参数mov表示移动的比特数当mov大于0时表示进行左移（往高位移动），当mov小于0时表示右移（往低位移动）*/
		static void Move(void* p, u64 startBitPosition, u64 bitsCount, s64 mov);
		/**
		@brief 比较两块内存区的大小，从高位往低位比较
		@param [传入]参数pSource表示用以进行比较的源数据
		@param [传入]参数startBitPositon表示源数据其实比特偏移
		@param [传入]参数bitsCount表示进行比较的比特数量
		@param [传入]参数pDestination表示用以进行比较的目标数据
		@param [传入,可选]参数destinationBitPosition表示目标其起始位置比特偏移量
		@return 返回值为1时，说明pSource表示的内容大于pDestination代表的内容，返回值为-1时则小于，返回值为0时说明两个区域的内容完全一样
		@note pSource和pDestination所表示的内存区域可以重叠，被移空的位置用0补充*/
		static int Compare(void const* pSource, u64 startBitPositon, u64 bitsCount, void const* pDestination, u64 destinationBitPosition = 0);
		/**
		@brief 比较两块内存区的大小，从高位往低位比较
		@param [传入]参数pSource表示用以进行比较的源数据
		@param [传入]参数bitsCount表示进行比较的比特数量
		@param [传入]参数pDestination表示用以进行比较的目标数据
		@param [传入,可选]参数destinationBitPosition表示目标其起始位置比特偏移量
		@return 返回值为1时，说明pSource表示的内容大于pDestination代表的内容，返回值为-1时则小于，返回值为0时说明两个区域的内容完全一样
		@note pSource和pDestination所表示的内存区域可以重叠*/
		static int  Compare(void* pSource, u64 bitsCount, void* pDestination, u64 destinationBitPosition = 0) { return Bits::Compare(pSource, 0, bitsCount, pDestination, destinationBitPosition); }
		/**
		@brief 比较两块内存区的大小，按高位对齐，从高位往低位比较
		@param [传入]参数p1表示用以进行比较的源数据（unsigned long long型数组）
		@param [传入]参数p2表示用以进行比较的目标数据（unsigned long long型数组）
		@param [传入]参数len1表示p1所代表数组的元素数
		@param [传入]参数len2表示p2所代表数组的元素数
		@return 返回值为1时，说明p1表示的内容大于p2代表的内容，返回值为-1时则小于，返回值为0时说明两个区域的内容完全一样
		@note p1和p2所表示的内存区域可以重叠.当len1和len2不等时，p1与p2各自代表的内容按高位对齐进行比较，末端用0补齐*/
		static int CompareHigh64(cu64*p1, cu64*p2, size_t len1, size_t len2);
		/**
		@brief 获取某比特位上的内容
		@param [传入]参数pSource表示需要获取内存
		@param [传入]参数bitPosition表示获取位置比特偏移量
		@return 当指定位置的内容为1时返回true，否则返回false*/
		static inline bool Get(const void* pSource, index_t bitPosition)
		{
			bitPosition += ((size_t)pSource&(sizeof(size_t) - 1)) * 8;
			size_t*ps = (size_t*)((size_t)pSource & (~(sizeof(size_t) - 1)));

			if (bitPosition < 0) { ps += (bitPosition - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); bitPosition &= (sizeof(size_t) * 8) - 1; }
			else if (bitPosition >= (index_t)(sizeof(size_t) * 8)) { ps += bitPosition / ((index_t)sizeof(size_t) * 8); bitPosition &= (sizeof(size_t) * 8) - 1; }

			return (*ps >> (bitPosition & (sizeof(size_t) * 8 - 1))) & 1;
		}
		/**
		@brief 在指定的比特位起获取size_t大小的内容
		@param [传入]参数pSource表示数据指针
		@param [传入]参数bitPosition表示起始位偏移
		@return 返回获取到的内容
		@note 该函数不做指针为NULL检查*/
		static inline size_t GetX(const void* pSource, index_t bitPosition)
		{
			bitPosition += ((size_t)pSource&(sizeof(size_t) - 1)) * 8;
			size_t* ps = (size_t*)((size_t)pSource & (~(sizeof(size_t) - 1)));
			if (bitPosition < 0) { ps += (bitPosition - (index_t)(sizeof(size_t) * 8 - 1)) / ((index_t)sizeof(size_t) * 8); bitPosition &= (sizeof(size_t) * 8) - 1; }
			else if (bitPosition >= (index_t)(sizeof(size_t) * 8)) { ps += bitPosition / ((index_t)sizeof(size_t) * 8); bitPosition &= (sizeof(size_t) * 8) - 1; }
			return bitPosition == 0 ? *ps : ((*ps >> bitPosition) | (*(ps + 1) << (sizeof(size_t) * 8 - bitPosition)));
		}
		/**
		@brief 将p和len所代表数组指定位置及其后的内容置0并舍入
		@param [传入,写出]参数p代表要进行操作的unsigned long long数组
		@param [传入]参数len代表数组p的元素数
		@param [传入]参数mov表示指定位置与最高位的偏移量，当mov>0时全内容置0，当mov==0时对最高位进行舍入操作
		@return 返回进位*/
		static bool SelfLimitBitsRoundHigh64(u64* p, u64 len, s64 mov);
		/**
		@brief 在p和len所代表的数组的指定位上加1，返回进位
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表需要进行操作的数组p的元素数
		@param [传入]参数mov代表指定位偏移（0代表最低位），超出范围时将不起作用
		@return 当相加产生进位时返回true，否则返回false*/
		static bool SelfPlusOne64(u64*p, u64 len, s64 mov);
		/**
		@brief 在p和len所代表的数组的指定位上加1（越下限时舍入），返回进位
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表需要进行操作的数组元素数
		@param [传入]参数mov代表指定位偏移（0代表最低位），超出范围上限时将不起作用，低于下限1位时舍入，
		@return 当相加产生进位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator++或者operator--运算*/
		static bool SelfPlusOneRound64(u64*p, u64 len, s64 mov);
		/**
		@brief 在p和len所代表的数组的指定位上加上一个64位无符号数字num，返回进位
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表需要进行操作的数组元素数
		@param [传入]参数num代表加数num
		@param [传入]参数mov代表num的位偏移（0代表最低位）。num按此偏移后超出len限制范围上下限的部分将被忽略
		@return 当相加产生进位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+=(int)或者operator-=(int)运算*/
		static bool SelfPlusInt64(u64*p, u64 len, u64 num, s64 mov);
		/**
		@brief 在p和len所代表的数组的指定位上加上一个64位无符号数字num（越下限时舍入），返回进位
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表需要进行操作的数组元素数
		@param [传入]参数num代表加数num
		@param [传入]参数mov代表num的位偏移（0代表最低位）。num按此偏移后超出len限制范围上限的部分将被忽略，低于下限的部分将进行自动舍入
		@return 当相加产生进位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+=(int)或者operator-=(int)运算*/
		static bool SelfPlusIntRound64(u64*p, u64 len, u64 num, s64 mov);
		/**
		@brief 在pDest和lenDest所代表的数组的指定位上加上pSource和lenSource所指定的内容，返回进位
		@param [传入,写出]参数pDest代表需要进行操作的unsigned long long[]数组
		@param [传入]参数lenDest代表需要进行操作的pDest数组元素数
		@param [传入]参数pSource代表加数unsigned long long数组
		@param [传入]参数lenSource代表加数pSource数组元素数
		@param [传入]参数mov代表加数pSource数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。pSource按此偏移后超出len限制范围上下限的部分将被忽略
		@return 当相加产生进位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+=()或者operator-=()运算*/
		static bool SelfPlus64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov);
		/**
		@brief 在pDest和lenDest所代表的数组的指定位上加上pSource和lenSource所指定的内容（越下限部分舍入），返回进位
		@param [传入,写出]参数pDest代表需要进行操作的unsigned long long[]数组
		@param [传入]参数lenDest代表需要进行操作的pDest数组元素数
		@param [传入]参数pSource代表加数unsigned long long数组
		@param [传入]参数lenSource代表加数pSource数组元素数
		@param [传入]参数mov代表加数pSource数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。pSource按此偏移后超出len限制范围上限的部分将被忽略，超出下限的部分将进行舍入操作
		@return 当相加产生进位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+=()或者operator-=()运算*/
		static bool SelfPlusRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的1叠加，然后将结果保存到pDest和lenDest所代表的数组中
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数
		@param [传入]参数pSource表示加数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0代表最低位）
		@param [传入]参数mov代表指定位相对pDest代表数组最低位的偏移（0代表最低位），超出范围时将不起作用
		@return 当相加产生进位时返回true，否则返回false*/
		static bool PlusOne64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 movSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的1叠加，然后将结果保存到pDest和lenDest所代表的数组中（越下限部分舍入）
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数
		@param [传入]参数pSource表示加数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0代表最低位）
		@param [传入]参数mov代表指定位相对pDest代表数组最低位的偏移（0代表最低位），超出上限时将被忽略，低于下限1位时进行舍入
		@return 当相加产生进位时返回true，否则返回false*/
		static bool PlusOneRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 movSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的64位数字num叠加，然后将结果保存到pDest和lenDest所代表的数组中
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数
		@param [传入]参数pSource表示加数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0代表最低位），超出上下限部分将被忽略
		@param [传入]参数mov代表指定位相对pDest代表数组最低位的偏移（0代表最低位），超出上下限部分将被忽略
		@return 当相加产生进位时返回true，否则返回false*/
		static bool PlusInt64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的64位数字num叠加，然后将结果保存到pDest和lenDest所代表的数组中（越下限部分舍入）
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数
		@param [传入]参数pSource表示加数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数num表示另一个加数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0代表最低位），超出上下限部分将被忽略
		@param [传入]参数mov表示num相对pDest代表数组最低位的偏移（0代表最低位），超出上下限部分将被忽略
		@return 返回进位（有可能返回进位2）
		@note 该函数可以用于二进制数字的operator + 或者operator - 运算。该函数有可能返回2：当两个加数都是全1且都越下限时,即lenDest为0*/
		static index_t PlusIntRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov);
		/**
		@brief 在将p1和len1所代表的数组与p2和len2所代表的数组按指定指定偏移进行叠加，并将结果保存到pDest中，超出pDest和lenDest所表示范围的内容将被忽略
		@param [传入,写出]参数pDest代表需要进行输出的unsigned long long[]数组
		@param [传入]参数lenDest代表需要进行输出的pDest数组元素数
		@param [传入]参数p1代表加数1的unsigned long long[]数组
		@param [传入]参数len1代表加数1数组元素数
		@param [传入]参数p2代表加数2的unsigned long long[]数组
		@param [传入]参数len2代表加数2数组元素数
		@param [传入]参数mov1代表加数p1数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p1按此偏移后超出lenDest限制范围上下限的部分将被忽略
		@param [传入]参数mov2代表加数p2数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p2按此偏移后超出lenDest限制范围上下限的部分将被忽略
		@return 当相加产生进位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+或者operator-运算*/
		static bool Plus64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2);
		/**
		@brief 在将p1和len1所代表的数组与p2和len2所代表的数组按指定指定偏移进行叠加，并将结果保存到pDest中，超出pDest和lenDest所表示范围上限的内容将被忽略，超出下限的内容将进行舍入
		@param [传入,写出]参数pDest代表需要进行输出的unsigned long long[]数组
		@param [传入]参数lenDest代表需要进行输出的pDest数组元素数
		@param [传入]参数p1代表加数1的unsigned long long[]数组
		@param [传入]参数len1代表加数1数组元素数
		@param [传入]参数p2代表加数2的unsigned long long[]数组
		@param [传入]参数len2代表加数2数组元素数
		@param [传入]参数mov1代表加数p1数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p1按此偏移后超出lenDest限制范围上限的部分将被忽略，超出下限的内容将进行舍入
		@param [传入]参数mov2代表加数p2数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p2按此偏移后超出lenDest限制范围上限的部分将被忽略，超出下限的内容将进行舍入
		@return 返回进位
		@note 该函数可以用于二进制数字的operator+或者operator-运算。该函数有可能返回2：当两个加数都是全1且都越下限时*/
		static index_t PlusRound64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2);
		/**
		@brief 在p和len所代表的数组的指定位上减1，返回借位
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表数组p的元素数
		@param [传入]参数mov代表指定位偏移（0代表最低位，1代表左移1位，-1代表右移1位），超出范围时将不起作用
		@return 当相减产生借位时返回true，否则返回false*/
		static inline bool SelfMinusOne64(u64*p, u64 len, s64 mov)
		{
			if (mov >= (s64)len * 64 || mov < 0)return false;//不在数组范围内
			p += mov / 64;
			len -= mov / 64;
			mov = 1ull << (mov & 63);
			if (*p >= (u64)mov) { *p -= mov; return false; }
			*p -= mov;
			for (u64 i = 1; i != len; ++i)if (p[i]-- != 0)return false;
			return true;
		}
		/**
		@brief 在p和len所代表的数组的指定位上减1，返回借位（下限舍入）
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表数组p的元素数
		@param [传入]参数mov代表指定位偏移（0代表最低位，1代表左移1位，-1代表最低位右移1位），超出数组上限时将不起作用，低于数组下限1位时对结果进行舍入操作
		@return 当相减产生借位时返回true，否则返回false
		@note 由于低于下限1位时舍入后又进位，因此该函数跟SelfMinusOne64完全一样*/
		static inline bool SelfMinusOneRound64(u64*p, u64 len, s64 mov) { return SelfMinusOne64(p, len, mov); }
		/**
		@brief 将p和len所代表的数组减去一个按指定位移量偏移的数字，返回借位
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表数组p的元素数
		@param [传入]参数num代表减数
		@param [传入]参数mov代表num位移量（0代表num最低位与数组最低位对齐，1代表左移1位，-1代表最低位右移1位），位移后超出数组范围的部分将不起作用
		@return 当相减产生借位时返回true，否则返回false*/
		static bool SelfMinusInt64(u64*p, u64 len, u64 num, s64 mov);
		/**
		@brief 将p和len所代表的数组减去一个按指定位移量偏移的数字num，返回借位
		@param [传入,写出]参数p代表需要进行操作的unsigned long long[]数组
		@param [传入]参数len代表数组p的元素数
		@param [传入]参数num代表减数
		@param [传入]参数mov代表num位移量（0代表num最低位与数组最低位对齐，1代表左移1位，-1代表最低位右移1位），位移后超出数组上限的部分将不起作用，超出下限的部分进行舍入
		@return 当相减产生借位时返回true，否则返回false*/
		static bool SelfMinusIntRound64(u64*p, u64 len, u64 num, s64 mov);
		/**
		@brief 在pDest和lenDest所代表的数组的指定位上减去pSource和lenSource所指定的内容，按低位对齐，返回借位
		@param [传入,写出]参数pDest代表需要进行操作的unsigned long long[]数组
		@param [传入]参数lenDest代表需要进行操作的pDest数组元素数
		@param [传入]参数pSource代表减数unsigned long long数组
		@param [传入]参数lenSource代表减数pSource数组元素数
		@param [传入]参数mov代表减数pSource数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。pSource按此偏移后超出len限制范围上下限的部分将被忽略
		@return 当相减产生借位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+=()或者operator-=()运算*/
		static bool SelfMinus64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov);
		/**
		@brief 在pDest和lenDest所代表的数组的指定位上减去pSource和lenSource所指定的内容，按低位对齐，返回借位
		@param [传入,写出]参数pDest代表需要进行操作的unsigned long long[]数组
		@param [传入]参数lenDest代表需要进行操作的pDest数组元素数
		@param [传入]参数pSource代表减数unsigned long long数组
		@param [传入]参数lenSource代表减数pSource数组元素数
		@return 当相减产生借位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+=()或者operator-=()运算*/
		static bool SelfMinus64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource);
		/**
		@brief 在pDest和lenDest所代表的数组的指定位上减去pSource和lenSource所指定的内容（越下限部分舍入），返回借位
		@param [传入,写出]参数pDest代表需要进行操作的unsigned long long[]数组（被减数）
		@param [传入]参数lenDest代表需要进行操作的pDest数组元素数
		@param [传入]参数pSource代表减数unsigned long long数组
		@param [传入]参数lenSource代表减数pSource数组元素数
		@param [传入]参数mov代表减数pSource数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。pSource按此偏移后超出len限制范围上限的部分将被忽略，超出下限的部分将进行舍入操作
		@return 当相加产生进位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+=()或者operator-=()运算*/
		static bool SelfMinusRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的1相减，然后将结果保存到pDest和lenDest所代表的数组中
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数
		@param [传入]参数pSource表示加数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0表示两者最低位对齐）
		@param [传入]参数mov代表指定位相对pDest代表数组最低位的偏移（0代表最低位），超出范围时将不起作用
		@return 当相减产生借位时返回true，否则返回false*/
		static bool MinusOne64(u64 *pDest, u64 lenDset, cu64*pSource, u64 lenSource, s64 movSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的1相减，然后将结果保存到pDest和lenDest所代表的数组中
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数
		@param [传入]参数pSource表示加数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0表示两者最低位对齐），超出上限时将不起作用，低于下限部分对结果进行舍入
		@param [传入]参数mov代表要进行-1操作的位相对pDest代表数组最低位的偏移（0代表最低位），超出上限时将不起作用，低于下限部分对结果进行舍入
		@return 当相减舍入产生进位时返回1，产生借位时返回-1，否则返回0*/
		static index_t MinusOneRound64(u64 *pDest, u64 lenDset, cu64*pSource, u64 lenSource, s64 movSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的64位数字num相减，然后将结果保存到pDest和lenDest所代表的数组中
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数，两者共同表示数组在内存中的区域
		@param [传入]参数pSource表示被减数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数num表示减数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0代表最低位），超出写出数组上下限部分将被忽略
		@param [传入]参数mov代表num相对pDest代表数组最低位的偏移（0代表最低位），位移后超出写出数组上下限部分将被忽略
		@return 当相减产生借位时返回true，否则返回false*/
		static bool MinusInt64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov);
		/**
		@brief 将pSource和lenSource所代表的数组按指定位偏移，与按指定位偏移的64位数字num相减，然后将结果舍入后保存到pDest和lenDest所代表的数组中
		@param [传入,写出]参数pDest代表需要进行写入的目标unsigned long long[]数组
		@param [传入]参数lenDest表示pDest数组元素数，两者共同表示数组在内存中的区域
		@param [传入]参数pSource表示被减数数组
		@param [传入]参数lenSource表示pSource数组元素数
		@param [传入]参数num表示减数
		@param [传入]参数movSource代表pSource代表数组最低位相对pDest代表数组最低位的偏移（0代表最低位），超出写出数组上限部分将被忽略,低于下限部分计算结果进行舍入
		@param [传入]参数mov代表num相对pDest代表数组最低位的偏移（0代表最低位），位移后超出写出数组上限部分将被忽略，低于下限部分计算结果进行舍入
		@return 当舍入产生进位时返回1，产生借位时返回-1，其它返回0*/
		static index_t MinusIntRound64(u64*pDest, u64 lenDest, cu64*pSource, u64 lenSource, u64 num, s64 movSource, s64 mov);
		/**
		@brief 在将p1和len1所代表的数组与p2和len2所代表的数组分别按指定偏移量偏移后进行相减，并将结果保存到pDest中，超出pDest和lenDest所表示范围的内容将被忽略
		@param [传入,写出]参数pDest代表输出的目标unsigned long long[]数组
		@param [传入]参数lenDest代表输出的目标pDest数组元素数
		@param [传入]参数p1代表被减数的unsigned long long[]数组
		@param [传入]参数len1代表被减数数组元素数
		@param [传入]参数p2代表减数的unsigned long long[]数组
		@param [传入]参数len2代表减数数组元素数
		@param [传入]参数mov1代表被减数p1数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p1按此偏移后超出lenDest限制范围上下限的部分将被忽略
		@param [传入]参数mov2代表减数p2数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p2按此偏移后超出lenDest限制范围上下限的部分将被忽略
		@return 当相减产生借位时返回true，否则返回false
		@note 该函数可以用于二进制数字的operator+或者operator-运算*/
		static bool Minus64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2);
		/**
		@brief 在将p1和len1所代表的数组与p2和len2所代表的数组分别按指定偏移量偏移后进行相减，并将结果按舍入保存到pDest中
		@param [传入,写出]参数pDest代表输出的目标unsigned long long[]数组
		@param [传入]参数lenDest代表输出的目标pDest数组元素数
		@param [传入]参数p1代表被减数的unsigned long long[]数组
		@param [传入]参数len1代表被减数数组元素数
		@param [传入]参数p2代表减数的unsigned long long[]数组
		@param [传入]参数len2代表减数数组元素数
		@param [传入]参数mov1代表被减数p1数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p1按此偏移后超出lenDest限制范围上限的部分将被忽略，超出下限的部分按结果舍入
		@param [传入]参数mov2代表减数p2数组低位相对pDest数组低位的位偏移（0代表两者最低位对齐）。p2按此偏移后超出lenDest限制范围上限的部分将被忽略，超出下限的部分按结果舍入
		@return 当舍入产生进位时返回1，相减产生借位时返回-1，其它返回0
		@note 该函数可以用于二进制数字的operator+或者operator-运算*/
		static index_t MinusRound64(u64*pDest, u64 lenDest, cu64*p1, u64 len1, cu64*p2, u64 len2, s64 mov1, s64 mov2);
		/**
		@brief 将p和len所代表的数组乘上一个32位整数num，按低位对齐，并返回溢出内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个32位乘数
		@return 返回相乘后溢出的内容，即相乘的结果由返回值和数组p共同表示*/
		static u32 SelfMultiplyInt32Low32(u32*p, size_t len, u32 num);
		/**
		@brief 将p和len所代表的数组乘上一个32位整数num，按低位对齐，并返回溢出内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个32位乘数
		@return 返回相乘后溢出的内容，即相乘的结果由返回值和数组p共同表示*/
		static inline u32 SelfMultiplyInt32Low64(u64*p, size_t len, u32 num) { return SelfMultiplyInt32Low32((u32*)p, len << 1, num); }
		/**
		@brief 将p和len所代表的数组乘上一个64位整数num，按低位对齐，并返回溢出内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个64位乘数
		@return 返回相乘后溢出的内容，即相乘的结果由返回值和数组p共同表示*/
		static u64 SelfMultiplyInt64Low32(u32*p, size_t len, u64 num);
		/**
		@brief 将p和len所代表的数组乘上一个64位整数num，按低位对齐，并返回溢出内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个64位乘数
		@return 返回相乘后溢出的内容，即相乘的结果由返回值和数组p共同表示*/
		static u64 SelfMultiplyInt64Low64(u64*p, size_t len, u64 num);
		/**
		@brief 将p和len所代表的数组乘上一个32位整数num，按高位对齐，并返回截去内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个32位乘数
		@return 返回相乘后低于下限截去的内容，即相乘的结果由数组p和返回值共同表示*/
		static u32 SelfMultiplyInt32High32(u32*p, size_t len, u32 num);
		/**
		@brief 将p和len所代表的数组乘上一个32位整数num，按高位对齐，并返回截去内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个32位乘数
		@return 返回相乘后低于下限截去的内容，即相乘的结果由数组p和返回值共同表示*/
		static u32 SelfMultiplyInt32High64(u64*p, size_t len, u32 num) { return SelfMultiplyInt32High32((u32*)p, len << 1, num); }
		/**
		@brief 将p和len所代表的数组乘上一个64位整数num，按高位对齐，并返回下限截去内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个64位乘数
		@return 返回相乘后下限截去的内容，即相乘的结果由数组p和返回值共同表示*/
		static u64 SelfMultiplyInt64High32(u32*p, size_t len, u64 num);
		/**
		@brief 将p和len所代表的数组乘上一个64位整数num，按高位对齐，并返回下限截去内容
		@param [传入,写出]参数p表示准备进行乘法操作的数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个64位乘数
		@return 返回相乘后下限截去的内容，即相乘的结果由数组p和返回值共同表示*/
		static u64 SelfMultiplyInt64High64(u64*p, size_t len, u64 num);
		/**
		@brief 将pSource和lenSource所代表的数组乘上一个32位整数num，按低位对齐，并返回pDest的溢出内容
		@param [写出]参数pDest表示准备进行结果写出的数组
		@param [传入]参数lenDest表示数组pDest的元素数
		@param [传入]参数pSource表示乘数1
		@param [传入]参数len表示数组pSource的元素数
		@param [传入]参数num表示一个32位整数（乘数2）
		@return 返回相乘后溢出的32bit内容，即相乘的结果由返回值和数组pDest共同表示
		@note 如果pDest数组大小不足以容纳输出结果，那么将按低位对齐输出尽量多的结果
		@note 源数据与目标数据不可重叠*/
		static u32 MultiplyInt32Low32(u32 *pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num);
		/**
		@brief 将pSource和lenSource所代表的数组乘上一个32位整数num，按低位对齐，并返回pDest的溢出内容
		@param [写出]参数pDest表示准备进行结果写出的数组
		@param [传入]参数lenDest表示数组pDest的元素数
		@param [传入]参数pSource表示乘数1
		@param [传入]参数len表示数组pSource的元素数
		@param [传入]参数num表示一个32位整数（乘数2）
		@return 返回相乘后溢出的32bit内容，即相乘的结果由返回值和数组pDest共同表示
		@note 如果pDest数组大小不足以容纳输出结果，那么将按低位对齐输出尽量多的结果
		@note 源数据与目标数据不可重叠*/
		static inline u32 MultiplyInt32Low64(u64 *pDest, size_t lenDest, cu64*pSource, size_t lenSource, u32 num)
		{
			return MultiplyInt32Low32((u32*)pDest, lenDest << 1, (u32*)pSource, lenSource << 1, num);
		}
		/**
		@brief 将pSource和lenSource所代表的数组乘上一个64位整数num，按低位对齐，并返回pDest的溢出内容
		@param [写出]参数pDest表示准备进行结果写出的数组
		@param [传入]参数lenDest表示数组pDest的元素数
		@param [传入]参数pSource表示乘数1
		@param [传入]参数len表示数组pSource的元素数
		@param [传入]参数num表示一个64位整数（乘数2）
		@return 返回相乘后溢出的64bit内容，即相乘的结果由返回值和数组pDest共同表示
		@note 如果pDest数组大小不足以容纳输出结果，那么将按低位对齐输出尽量多的结果
		@note 源数据与目标数据不可重叠*/
		static u64 MultiplyInt64Low32(u32*pDest, size_t lenDest, cu32*pSource, size_t lenSource, u64 num);
		/**
		@brief 将pSource和lenSource所代表的数组乘上一个64位整数num，按低位对齐，并返回pDest的溢出内容
		@param [写出]参数pDest表示准备进行结果写出的数组
		@param [传入]参数lenDest表示数组pDest的元素数
		@param [传入]参数pSource表示乘数1
		@param [传入]参数len表示数组pSource的元素数
		@param [传入]参数num表示一个64位整数（乘数2）
		@return 返回相乘后溢出的64bit内容，即相乘的结果由返回值和数组pDest共同表示
		@note 如果pDest数组大小不足以容纳输出结果，那么将按低位对齐输出尽量多的结果
		@note 源数据与目标数据不可重叠*/
		static u64 MultiplyInt64Low64(u64*pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num);
		/**
		@brief 将pSource和lenSource所代表的数组乘上一个32位整数num，按高位对齐，并返回pDest下限截去内容
		@param [写出]参数pDest表示准备进行结果写出的数组
		@param [传入]参数lenDest表示数组pDest的元素数
		@param [传入]参数pSource表示乘数1
		@param [传入]参数len表示数组pSource的元素数
		@param [传入]参数num表示一个32位整数（乘数2）
		@return 返回相乘后pDest下限截去的32bit内容，即相乘的结果由返回值和数组pDest共同表示
		@note 如果pDest数组大小不足以容纳输出结果，那么将按高位对齐输出尽量多的结果
		@note 源数据与目标数据不可重叠*/
		static u32 MultiplyInt32High32(u32*pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num);
		/**
		@brief 将pSource和lenSource所代表的数组乘上一个32位整数num，按高位对齐，并返回pDest下限截去内容
		@param [写出]参数pDest表示准备进行结果写出的数组
		@param [传入]参数lenDest表示数组pDest的元素数
		@param [传入]参数pSource表示乘数1
		@param [传入]参数len表示数组pSource的元素数
		@param [传入]参数num表示一个32位整数（乘数2）
		@return 返回相乘后pDest下限截去的32bit内容，即相乘的结果由返回值和数组pDest共同表示
		@note 如果pDest数组大小不足以容纳输出结果，那么将按高位对齐输出尽量多的结果
		@note 源数据与目标数据不可重叠*/
		static u32 MultiplyInt32High64(u64*pDest, size_t lenDest, cu64*pSource, size_t lenSource, u32 num) { return MultiplyInt32High32((u32*)pDest, lenDest << 1, (u32*)pSource, lenSource << 1, num); }
		/**
		@brief 将pSource和lenSource所代表的数组乘上一个64位整数num，按高位对齐，并返回pDest下限截去内容
		@param [写出]参数pDest表示准备进行结果写出的数组
		@param [传入]参数lenDest表示数组pDest的元素数
		@param [传入]参数pSource表示一个unsigned long long数组（乘数1）
		@param [传入]参数len表示数组pSource的元素数
		@param [传入]参数num表示一个64位整数（乘数2）
		@return 返回相乘后pDest下限截去的64bit内容，即相乘的结果由数组pDest和返回值共同表示
		@note 如果pDest数组大小不足以容纳输出结果，那么将按高位对齐输出尽量多的结果
		@note 源数据与目标数据不可重叠*/
		static u64 MultiplyInt64High64(u64*pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按低位对齐，并返回溢出的32bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned long数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned long数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回溢出的32位数值，否则返回0
		@note 源数据与目标数据不可重叠*/
		static u32 MultiplyLow32(u32*pDest, size_t lenDest, cu32* pm1, size_t len1, cu32*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按低位对齐，并返回溢出的64bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned long long数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned long long数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回溢出的32位数值，否则返回0
		@note 源数据与目标数据不可重叠*/
		static u64 MultiplyLow64(u64*pDest, size_t lenDest, cu64* pm1, size_t len1, cu64*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按低位对齐，并返回溢出的8bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned char数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned char数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回溢出的8位数值，否则返回0
		@note 源数据与目标数据可以重叠
		@note 使用该函数必须包含LK::Equation::DoubleComplex类型
		@note 由于FFT计算使用的是double型数据，受其精度限制，要求输入的数组总字节数都不得超过2^32*/
		static u8 MultiplyFFTLow8(u8*pDest, size_t lenDest, cu8* pm1, size_t len1, cu8*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按高对齐，并返回低位截取掉的8bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned short数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned short数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回低位截取掉的8位数值，否则返回0
		@note 源数据与目标数据可以重叠
		@note 使用该函数必须包含LK::Equation::DoubleComplex类型
		@note 由于FFT计算使用的是double型数据，受其精度限制，要求输入的数组总字节数不得超过2^32,否则请考虑MultiplyFFTHigh32*/
		static u8 MultiplyFFTHigh8(u8*pDest, size_t lenDest, cu8* pm1, size_t len1, cu8*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按低位对齐，并返回溢出的16bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned short数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned short数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回溢出的16位数值，否则返回0
		@note 源数据与目标数据可以重叠
		@note 使用该函数必须包含LK::Equation::DoubleComplex类型
		@note 由于FFT计算使用的是double型数据，受其精度限制，要求输入的数组元素数都不得超过2^20*/
		static u16 MultiplyFFTLow(u16*pDest, size_t lenDest, cu16* pm1, size_t len1, cu16*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按高对齐，并返回低位截取掉的16bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned short数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned short数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回低位截取掉的16位数值，否则返回0
		@note 源数据与目标数据可以重叠
		@note 使用该函数必须包含LK::Equation::DoubleComplex类型
		@note 由于FFT计算使用的是double型数据，受其精度限制，要求输入的数组总比特数不得超过2^16,否则请考虑MultiplyFFTHigh32*/
		static u16 MultiplyFFTHigh(u16*pDest, size_t lenDest, cu16* pm1, size_t len1, cu16*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按高对齐，并返回低位截取掉的32bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned long long数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned long long数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回低位截取掉的64位数值，否则返回0
		@note 源数据与目标数据可以重叠
		@note 使用该函数必须包含LK::Equation::Complex128类型*/
		static u32 MultiplyFFTHigh32(u32*pDest, size_t lenDest, cu32* pm1, size_t len1, cu32*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按高位对齐，并返回下限截取掉的32bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned long数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned long数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回下限截取掉的数值的高32位，否则返回0
		@note 源数据与目标数据不可重叠*/
		static u32 MultiplyHigh32(u32*pDest, size_t lenDest, cu32* pm1, size_t len1, cu32*pm2, size_t len2);
		/**
		@brief 将数组pm1[len1]与数组pm2[len2]相乘的结果保存到数组pDest[lenDest]中，三者按高位对齐，并返回下限截取掉的64bit内容
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pm1表示一个unsigned long long数组（乘数1）
		@param [传入]参数len1表示pm1数组的元素数
		@param [传入]参数pm2表示一个unsigned long long数组（乘数2）
		@param [传入]参数len2表示pm2数组的元素数
		@return 当pDest数组无法容纳乘积结果时，返回下限截取掉的数值的高64位，否则返回0
		@note 源数据与目标数据不可重叠
		@note 认为乘数、商的最高位指数均为-1*/
		static u64 MultiplyHigh64(u64*pDest, size_t lenDest, cu64* pm1, size_t len1, cu64*pm2, size_t len2);
		/**
		@brief 将p[len]数组除以一个32位无符号整数num，（按低位对齐），返回余数
		@param [传入,写出]参数p代表被除数数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个32位无符号除数
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u32 SelfDivideInt32Low32(u32 *p, size_t len, u32 num);
		/**
		@brief 将p[len]数组除以一个32位无符号整数num，（按低位对齐），返回余数
		@param [传入,写出]参数p代表被除数数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个32位无符号除数
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u32 SelfDivideInt32Low64(u64*p, size_t len, u32 num);
		/**
		@brief 将p[len]数组除以一个64位无符号整数num，（按低位对齐），返回余数
		@param [传入,写出]参数p代表被除数数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个64位无符号除数
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u64 SelfDivideInt64Low32(u32 *p, size_t len, u64 num);
		/**
		@brief 将p[len]数组除以一个64位无符号整数num，（按低位对齐），返回余数
		@param [传入,写出]参数p代表被除数数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个64位无符号除数
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u64 SelfDivideInt64Low64(u64*p, size_t len, u64 num);
		/**
		@brief 将p[len]数组除以一个32位无符号整数num，（按高位对齐），返回余数
		@param [传入,写出]参数p代表被除数数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个32位无符号除数
		@param [传入]参数mov为true时，认为最高位权重为0；mov为false时，认为最高位权重为-1
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u32 SelfDivideInt32High32(u32 *p, size_t len, u32 num, bool mov = false);
		/**
		@brief 将p[len]数组除以一个64位无符号整数num，（按高位对齐），返回余数
		@param [传入,写出]参数p代表被除数数组
		@param [传入]参数len表示数组p的元素数
		@param [传入]参数num表示一个64位无符号除数
		@param [传入]参数mov为true时，认为最高位权重为0；mov为false时，认为最高位权重为-1
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u64 SelfDivideInt64High64(u64 *p, size_t len, u64 num, bool mov = false);
		/**
		@brief 将pSource[lenSource]数组除以一个32位无符号整数num，并将所得结果存储到数组pDest[lenDest]中，（按低位对齐），返回余数
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pSource代表被除数
		@param [传入]参数lenSource表示数组pSource的元素数
		@param [传入]参数num表示一个32位无符号除数
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u32 DivideInt32Low32(u32 *pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num);
		/**
		@brief 将pSource[lenSource]数组除以一个64位无符号整数num，并将所得结果存储到数组pDest[lenDest]中，（按低位对齐），返回余数
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pSource代表被除数
		@param [传入]参数lenSource表示数组pSource的元素数
		@param [传入]参数num表示一个64位无符号除数
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u64 DivideInt64Low64(u64 *pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num);
		/**
		@brief 将pSource[lenSource]数组除以一个32位无符号整数num，并将所得结果存储到数组pDest[lenDest]中，（按高位对齐），返回余数
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pSource代表被除数
		@param [传入]参数lenSource表示数组pSource的元素数
		@param [传入]参数num表示一个32位无符号除数
		@param [传入]参数mov为true时，表示商最高位权重为-1；false表示商最高位权重为0
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u32 DivideInt32High32(u32 *pDest, size_t lenDest, cu32*pSource, size_t lenSource, u32 num, bool mov = false);
		/**
		@brief 将pSource[lenSource]数组除以一个64位无符号整数num，并将所得结果存储到数组pDest[lenDest]中，（按高位对齐），返回余数
		@param [写出]参数pDest代表用以输出结果的数组
		@param [传入]参数lenDest表示pDest数组的元素数
		@param [传入]参数pSource代表被除数
		@param [传入]参数lenSource表示数组pSource的元素数
		@param [传入]参数num表示一个64位无符号除数
		@param [传入]参数mov为true时，表示商最高位权重为-1；false表示商最高位权重为0
		@return 当除数和被除数都不为0时返回余数，否则返回0
		@note 除数num为0时不会抛出异常*/
		static u64 DivideInt64High64(u64 *pDest, size_t lenDest, cu64*pSource, size_t lenSource, u64 num, bool mov = false);
		/**
		@brief 将p1[len1]除以p2[len2]的结果存储到p[len]数组中（按低位对齐）
		@param [写出]参数p代表结果数组
		@param [传入]参数len表示p数组的元素数
		@param [传入]参数p1代表被除数
		@param [传入]参数bitsCount1表示p1数组有数据比特数
		@param [传入]参数p2代表被除数
		@param [传入]参数bitsCount表示p2数组有数据比特数
		@param [写出,可选]参数pd代表余数数组
		@param [传入,可选]参数lend表示pd数组元素数*/
		static void DivideLow64(u64*p, size_t len, cu64*p1, u64 bitsCount1, cu64*p2, u64 bitsCount2, u64 *pd = NULL, size_t lend = 0);
		/**
		@brief 将p1[len1]除以p2[len2]的结果存储到p[len]数组中（按高位对齐）
		@param [写出]参数p代表结果数组
		@param [传入]参数len表示p数组的元素数
		@param [传入]参数p1代表被除数
		@param [传入]参数len1表示p1数组元素数
		@param [传入]参数p2代表被除数
		@param [传入]参数len2表示p2数组元素数
		@param [传入,可选]参数mov为true时表示商最高位权重为0，否则为-1
		@param [写出,可选]参数pd代表余数数组（高位对齐）
		@param [传入,可选]参数lend表示pd数组元素数
		@note 商的长度参数len2必须要匹配数组的有内容数据，要求最高位不为0*/
		static void DivideHigh64(u64*p, size_t len, cu64*p1, u64 len1, cu64*p2, u64 len2, bool mov = false, u64 *pd = NULL, size_t lend = 0);
		/**
		@brief 将p1[len1]除以p2[len2]的结果存储到p[len]数组中（按高位对齐）
		@param [写出]参数p代表结果数组
		@param [传入]参数len表示p数组的元素数
		@param [传入]参数bits表示生商位数
		@param [传入]参数p1代表被除数
		@param [传入]参数len1表示p1数组元素数
		@param [传入]参数p2代表被除数
		@param [传入]参数len2表示p2数组元素数
		@param [传入,可选]参数mov为true时表示商最高位权重为0，否则为-1
		@param [写出,可选]参数pd代表余数数组（高位对齐）
		@param [传入,可选]参数lend表示pd数组元素数
		@note 商的长度参数len2必须要匹配数组的有内容数据，要求最高位不为0
		@note 通常使用该函数指定产生整数的生商位数来求余
		@note 余数的最高位指数*/
		static void ModHigh64(u64*p, size_t len, u64 bits, cu64*p1, u64 len1, cu64*p2, u64 len2, bool mov = false, u64 *pd = NULL, size_t lend = 0);
		/**
		@brief 将pSource指向内存数据叠加到pDes指向内存中
		@param [传入,写出]参数pDest表示用以进行叠加和写出叠加结果的目标数组
		@param [传入]参数pSource表示用以进行叠加的源数组
		@param [传入]参数len表示元素数，要求pDes与pSource的元素数一样
		@return 如果相加结果溢出，那么将返回true，否则返回false
		@note 该函数可以用于二进制数字的operator++或者operator--运算*/
		static bool Plus64(u64 *pDes, cu64* pSource, size_t len);
		/**
		@brief 获取i后导1的比特数
		@param [传入]参数i表示一个被测的64位数字
		@return 返回值表示i后导1的比特数，比如RightOneCount64(2)将返回0，RightOneCount64(11)将返回2*/
		static index_t RightOneCount64(u64 i);
		/**
		@brief 将pSource所指向的sLen个内存块（每个内存块8字节）复制到pDest所指向的dLen个内存块中，并左移mov个比特位
		@param [传入]参数pSouece表示用以进行复制的源数据（unsigned long long数组）
		@param [传入]参数sLen表示源数据的元素数
		@param [传入,写出]参数pDest表示复制的目标内存（unsigned long long数组）
		@param [传入]参数dLen表示目标数组的元素数
		@param [传入]参数mov表示复制后继续进行的偏移量，mov>0时表示向左（高位）移动，mov<0表示向右（低位）移动。
		@note 超出范围的部分将被截断。被移空的位置用0补充，若目标左端（高位端）有空间剩余，则不做处理。复制源和目标位置可以重叠。*/
		static void CopyShift64(cu64* pSource, size_t sLen, u64* pDest, size_t dLen, s64 mov);
		/**
		@brief 将p指向的len个无符号内存块进行左移mov个比特。
		@param [传入,写出]参数p表示操作目标数组
		@param [传入]参数len表示p所表示数组的元素数
		@param [传入]参数mov表示移动偏移量。若mov<0表示右移（往低位），若mov>0表示左移（往高位）
		@return 返回移出的64bit内容
		@note 超出范围部分将被截断，被移空的位置用0补充*/
		static u64 Move64(u64* p, size_t len, s64 mov);
	};
}